/**
 * DTO基类
 * 提供通用数据转换方法
 */
class BaseDTO {
  /**
   * 从源模型创建DTO
   * @param {Object} sourceModel 源数据模型
   * @param {Object} mapping 字段映射 {目标字段: 源字段}
   * @returns {Object} DTO对象
   */
  static fromModel(sourceModel, mapping = {}) {
    if (!sourceModel) return null;
    
    const dto = {};
    
    // 应用映射规则
    for (const [targetField, sourceField] of Object.entries(mapping)) {
      if (typeof sourceField === 'function') {
        // 如果是函数，则调用函数获取值
        dto[targetField] = sourceField(sourceModel);
      } else if (sourceField.includes('.')) {
        // 处理嵌套字段 "user.name" => sourceModel.user.name
        const parts = sourceField.split('.');
        let value = sourceModel;
        for (const part of parts) {
          value = value && value[part];
        }
        dto[targetField] = value;
      } else {
        // 普通字段直接赋值
        dto[targetField] = sourceModel[sourceField];
      }
    }
    
    return dto;
  }
  
  /**
   * 批量转换模型列表
   * @param {Array} modelList 源模型列表
   * @param {Object} mapping 字段映射
   * @returns {Array} DTO对象列表
   */
  static fromModelList(modelList, mapping = {}) {
    if (!Array.isArray(modelList)) return [];
    
    return modelList.map(model => this.fromModel(model, mapping));
  }
  
  /**
   * 将DTO转换回模型对象
   * @param {Object} dto DTO对象
   * @param {Object} mapping 反向字段映射 {源字段: 目标字段}
   * @returns {Object} 模型对象
   */
  static toModel(dto, mapping = {}) {
    if (!dto) return null;
    
    const model = {};
    
    // 应用映射规则
    for (const [sourceField, targetField] of Object.entries(mapping)) {
      if (typeof targetField === 'function') {
        // 如果是函数，则调用函数设置值
        targetField(model, dto[sourceField]);
      } else if (targetField.includes('.')) {
        // 处理嵌套字段 "user.name" => model.user.name
        const parts = targetField.split('.');
        let current = model;
        for (let i = 0; i < parts.length - 1; i++) {
          const part = parts[i];
          if (!current[part]) current[part] = {};
          current = current[part];
        }
        current[parts[parts.length - 1]] = dto[sourceField];
      } else {
        // 普通字段直接赋值
        model[targetField] = dto[sourceField];
      }
    }
    
    return model;
  }
}

module.exports = BaseDTO; 